package service

import (
	"context"
	"errors"
	"patient-srv/basic/config"
	"patient-srv/basic/inits"
	patient "patient-srv/basic/proto"
	"patient-srv/handler/model"
	"time"

	"gorm.io/gorm"
)

type PatientServiceServer struct {
	patient.UnimplementedPatientServiceServer
}

// Register 患者注册
func (s *PatientServiceServer) Register(ctx context.Context, req *patient.RegisterRequest) (*patient.RegisterResponse, error) {
	// 1. 验证短信验证码（这里简化处理，实际应该从Redis中验证）
	if req.SmsCode == "" {
		return &patient.RegisterResponse{
			Message: "验证码不能为空",
		}, nil
	}

	// 2. 检查手机号是否已注册
	if model.IsPhoneExists(config.GlobalDB, req.Phone) {
		return &patient.RegisterResponse{
			Message: "该手机号已注册",
		}, nil
	}

	// 3. 创建用户
	user := &model.User{
		Phone:    req.Phone,
		Password: model.HashPassword(req.Password),
	}

	if err := user.Create(config.GlobalDB); err != nil {
		return nil, err
	}

	return &patient.RegisterResponse{
		Message: "注册成功",
		UserId:  int64(user.ID),
	}, nil
}

// Login 患者登录
func (s *PatientServiceServer) Login(ctx context.Context, req *patient.LoginRequest) (*patient.LoginResponse, error) {
	// 1. 查询用户
	var user model.User
	err := user.GetByPhone(config.GlobalDB, req.Phone)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.LoginResponse{
				Message: "用户不存在",
			}, nil
		}
		return nil, err
	}

	// 2. 验证密码
	if !user.VerifyPassword(req.Password) {
		return &patient.LoginResponse{
			Message: "密码错误",
		}, nil
	}

	return &patient.LoginResponse{
		Message: "登录成功",
		UserId:  int64(user.ID),
		Phone:   user.Phone,
	}, nil
}

// GetPatientInfo 获取患者信息
func (s *PatientServiceServer) GetPatientInfo(ctx context.Context, req *patient.GetPatientInfoRequest) (*patient.PatientInfoResponse, error) {
	// 查询默认就诊人或第一个就诊人
	var patientModel model.Patient
	err := patientModel.GetDefaultByUserID(config.GlobalDB, req.UserId)

	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.PatientInfoResponse{
				Message: "暂无患者信息",
			}, nil
		}
		return nil, err
	}

	return &patient.PatientInfoResponse{
		Message: "获取成功",
		Patient: &patient.PatientInfo{
			Id:             patientModel.ID,
			UserId:         patientModel.UserID,
			Name:           patientModel.Name,
			Gender:         int32(patientModel.Gender),
			BirthDate:      patientModel.BirthDate,
			Phone:          patientModel.Phone,
			IdCard:         patientModel.IdCard,
			AllergyHistory: patientModel.AllergyHistory,
			MedicalHistory: patientModel.MedicalHistory,
			Relation:       patientModel.Relation,
			IsVerified:     patientModel.IsVerified,
			IsDefault:      patientModel.IsDefault,
			CreatedAt:      patientModel.CreatedAt.Format("2006-01-02 15:04:05"),
			UpdatedAt:      patientModel.UpdatedAt.Format("2006-01-02 15:04:05"),
		},
	}, nil
}

// UpdatePatientInfo 更新患者信息
func (s *PatientServiceServer) UpdatePatientInfo(ctx context.Context, req *patient.UpdatePatientInfoRequest) (*patient.BaseResponse, error) {
	// 查询患者信息
	var patientModel model.Patient
	err := patientModel.GetByID(config.GlobalDB, req.PatientId, req.UserId)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.BaseResponse{Message: "患者信息不存在"}, nil
		}
		return nil, err
	}

	// 准备更新信息
	updates := make(map[string]interface{})
	if req.Name != "" {
		updates["name"] = req.Name
	}
	if req.Gender > 0 {
		updates["gender"] = req.Gender
	}
	if req.BirthDate != "" {
		updates["birth_date"] = req.BirthDate
	}
	if req.Phone != "" {
		updates["phone"] = req.Phone
	}
	if req.AllergyHistory != "" {
		updates["allergy_history"] = req.AllergyHistory
	}
	if req.MedicalHistory != "" {
		updates["medical_history"] = req.MedicalHistory
	}

	// 调用模型方法更新
	if err := patientModel.Update(config.GlobalDB, updates); err != nil {
		return nil, err
	}

	return &patient.BaseResponse{Message: "更新成功"}, nil
}

// VerifyPatient 患者实名认证
func (s *PatientServiceServer) VerifyPatient(ctx context.Context, req *patient.VerifyPatientRequest) (*patient.BaseResponse, error) {
	// 查询患者信息
	var patientModel model.Patient
	err := patientModel.GetByID(config.GlobalDB, req.PatientId, req.UserId)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.BaseResponse{Message: "患者信息不存在"}, nil
		}
		return nil, err
	}

	// 调用模型方法进行实名认证
	if err := patientModel.Verify(config.GlobalDB, req.RealName, req.IdCard); err != nil {
		return nil, err
	}

	return &patient.BaseResponse{Message: "实名认证成功"}, nil
}

// GetPatientList 获取就诊人列表
func (s *PatientServiceServer) GetPatientList(ctx context.Context, req *patient.GetPatientListRequest) (*patient.PatientListResponse, error) {
	// 调用模型方法获取就诊人列表
	patients, err := model.GetPatientListByUserID(config.GlobalDB, req.UserId)
	if err != nil {
		return nil, err
	}

	// 数据转换
	var result []*patient.PatientInfo
	for _, p := range patients {
		result = append(result, &patient.PatientInfo{
			Id:             p.ID,
			UserId:         p.UserID,
			Name:           p.Name,
			Gender:         int32(p.Gender),
			BirthDate:      p.BirthDate,
			Phone:          p.Phone,
			IdCard:         p.IdCard,
			AllergyHistory: p.AllergyHistory,
			MedicalHistory: p.MedicalHistory,
			Relation:       p.Relation,
			IsVerified:     p.IsVerified,
			IsDefault:      p.IsDefault,
			CreatedAt:      p.CreatedAt.Format("2006-01-02 15:04:05"),
			UpdatedAt:      p.UpdatedAt.Format("2006-01-02 15:04:05"),
		})
	}

	return &patient.PatientListResponse{
		Message:  "获取成功",
		Patients: result,
	}, nil
}

// AddPatient 添加就诊人
func (s *PatientServiceServer) AddPatient(ctx context.Context, req *patient.AddPatientRequest) (*patient.BaseResponse, error) {
	// 构建患者模型
	patientModel := &model.Patient{
		UserID:     req.UserId,
		Name:       req.Name,
		Gender:     int(req.Gender),
		BirthDate:  req.BirthDate,
		Phone:      req.Phone,
		IdCard:     req.IdCard,
		Relation:   req.Relation,
		IsVerified: false,
	}

	// 调用模型方法创建（会自动处理默认就诊人逻辑）
	if err := patientModel.Create(config.GlobalDB); err != nil {
		return nil, err
	}

	return &patient.BaseResponse{Message: "添加成功"}, nil
}

// DeletePatient 删除就诊人
func (s *PatientServiceServer) DeletePatient(ctx context.Context, req *patient.DeletePatientRequest) (*patient.BaseResponse, error) {
	// 查询患者信息
	var patientModel model.Patient
	err := patientModel.GetByID(config.GlobalDB, req.PatientId, req.UserId)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.BaseResponse{Message: "患者信息不存在"}, nil
		}
		return nil, err
	}

	// 调用模型方法删除（会自动处理默认就诊人逻辑）
	if err := patientModel.Delete(config.GlobalDB, req.UserId); err != nil {
		return nil, err
	}

	return &patient.BaseResponse{Message: "删除成功"}, nil
}

// SendResetCode 发送重置密码验证码
func (s *PatientServiceServer) SendResetCode(ctx context.Context, req *patient.SendResetCodeRequest) (*patient.BaseResponse, error) {
	// 检查手机号是否已注册
	if !model.IsPhoneExists(config.GlobalDB, req.Phone) {
		return &patient.BaseResponse{Message: "该手机号未注册"}, nil
	}

	// 生成验证码（这里简化处理，实际应该生成随机验证码）
	// 注意：由于是演示环境，这里硬编码为123456以便测试
	code := "123456"

	// 存储验证码到Redis，设置过期时间
	key := "reset_code:" + req.Phone
	err := inits.RedisClient.Set(ctx, key, code, 10*time.Minute).Err()
	if err != nil {
		return nil, err
	}

	// TODO: 实际项目中这里应该调用短信服务发送验证码
	// fmt.Printf("验证码 %s 已发送到 %s\n", code, req.Phone)

	return &patient.BaseResponse{Message: "验证码发送成功"}, nil
}

// ResetPassword 重置密码
func (s *PatientServiceServer) ResetPassword(ctx context.Context, req *patient.ResetPasswordRequest) (*patient.BaseResponse, error) {
	// 检查手机号是否已注册
	var user model.User
	err := user.GetByPhone(config.GlobalDB, req.Phone)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return &patient.BaseResponse{Message: "该手机号未注册"}, nil
		}
		return nil, err
	}

	// 验证短信验证码
	key := "reset_code:" + req.Phone
	storedCode, err := inits.RedisClient.Get(ctx, key).Result()
	if err != nil {
		return &patient.BaseResponse{Message: "验证码已过期或不存在"}, nil
	}

	if storedCode != req.SmsCode {
		return &patient.BaseResponse{Message: "验证码错误"}, nil
	}

	// 删除已使用的验证码
	inits.RedisClient.Del(ctx, key)

	// 更新密码
	updates := map[string]interface{}{
		"password":  model.HashPassword(req.Password),
		"updated_at": time.Now(),
	}

	if err := config.GlobalDB.Model(&user).Updates(updates).Error; err != nil {
		return nil, err
	}

	return &patient.BaseResponse{Message: "密码重置成功"}, nil
}
